using System;
using NFreeMarker.Template;

namespace NFreeMarker.Core
{
    /**
     * A reference to a top-level variable
     */

    public sealed class Identifier : Expression // NOTE: Was internal
    {
        private readonly string _name;

        internal Identifier(string name)
        {
            _name = name;
        }

        protected override ITemplateModel _getAsTemplateModel(Environment env)
        {
            try
            {
                return env.GetVariable(_name);
            }
            catch (NullReferenceException)
            {
                if (env == null)
                {
                    throw new TemplateException(
                        "Variables are not available " +
                        "(certainly you are in a parse-time executed directive). The name of the variable " +
                        "you tried to read: " + _name, null);
                }
                throw;
            }
        }

        public override string ToString()
        {
            return _name;
        }

        public override string GetCanonicalForm()
        {
            return _name;
        }

        internal override bool IsLiteral()
        {
            return false;
        }

        protected override Expression DeepCloneImpl(string name, Expression subst)
        {
            if (_name == name)
            {
                return subst.DeepClone(null, null);
            }
            return new Identifier(_name);
        }
    }
}